<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Rich Paste to HTML Subset</title>
  <style>
  * {
    box-sizing: border-box;
  }
  
  body {
    font-family: Helvetica, Arial, sans-serif;
    max-width: 1000px;
    margin: 0 auto;
    padding: 20px;
    line-height: 1.5;
  }
  
  h1, h2 {
    color: #333;
  }
  
  #paste-area {
    width: 100%;
    min-height: 200px;
    padding: 15px;
    border: 2px dashed #ccc;
    border-radius: 4px;
    margin-bottom: 15px;
    font-size: 16px;
    font-family: Helvetica, Arial, sans-serif;
  }
  
  #paste-area:focus {
    outline: none;
    border-color: #4a88e5;
  }
  
  .info-text {
    color: #666;
    margin-bottom: 20px;
    font-style: italic;
  }
  
  #output-container {
    display: none;
    margin-top: 30px;
  }
  
  #html-output {
    width: 100%;
    height: 200px;
    padding: 10px;
    border: 1px solid #ddd;
    border-radius: 4px;
    font-family: monospace;
    font-size: 16px;
    margin-bottom: 15px;
    white-space: pre-wrap;
  }
  
  .button {
    background-color: #33aa44;
    color: white;
    border: none;
    padding: 10px 15px;
    font-size: 16px;
    border-radius: 4px;
    cursor: pointer;
    margin-right: 10px;
    margin-bottom: 20px;
  }
  
  .button:hover {
    background-color: #2a9038;
  }
  
  #preview-container {
    margin-top: 20px;
    border: 1px solid #eee;
    padding: 20px;
    border-radius: 4px;
  }
  
  #preview-content {
    font-family: Helvetica, Arial, sans-serif;
  }
  
  .success-message {
    color: green;
    font-weight: bold;
  }
  
  .tag-list {
    background-color: #f8f8f8;
    border-left: 4px solid #4a88e5;
    padding: 15px;
    margin-bottom: 20px;
  }
  
  .tag-list ul {
    margin: 0;
    padding-left: 20px;
  }
  </style>
</head>
<body>
  <h1>Rich Paste to HTML Subset</h1>
  
  <div class="tag-list">
    <h3>Supported HTML elements</h3>
    <ul>
      <li><strong>p</strong> - Paragraphs</li>
      <li><strong>strong</strong> - Bold text</li>
      <li><strong>em</strong> - Italic text</li>
      <li><strong>blockquote</strong> - Quoted text</li>
      <li><strong>code</strong> - Code snippets</li>
      <li><strong>a</strong> - Links (href attribute is preserved)</li>
      <li><strong>h1-h6</strong> - Headings</li>
      <li><strong>ul</strong> - Unordered lists</li>
      <li><strong>ol</strong> - Ordered lists</li>
      <li><strong>li</strong> - List items</li>
      <li><strong>dl</strong> - Definition lists</li>
      <li><strong>dt</strong> - Definition terms</li>
      <li><strong>dd</strong> - Definition descriptions</li>
    </ul>
  </div>
  
  <div id="paste-area" contenteditable="true"></div>
  <p class="info-text">Paste using Ctrl+V or ⌘+V to capture the rich text HTML. On mobile, use "Paste as text with formatting" from your context menu.</p>
  
  <div id="output-container">
    <h2>Clean HTML code</h2>
    <textarea id="html-output" readonly></textarea>
    <button id="copy-button" class="button">Copy HTML</button>
    <button id="clear-button" class="button">Clear all</button>
    
    <div id="preview-container">
      <h2>Preview</h2>
      <iframe id="preview-frame" style="width: 100%; height: 300px; border: 1px solid #ddd; border-radius: 4px;"></iframe>
    </div>
  </div>
  
  <script>
  // Function to escape HTML entities for display
  function escapeHtml(html) {
    return html
      .replace(/&/g, "&amp;")
      .replace(/</g, "&lt;")
      .replace(/>/g, "&gt;")
      .replace(/"/g, "&quot;")
      .replace(/'/g, "&#039;");
  }
  
  // Function to sanitize HTML and keep only allowed tags and attributes
  function sanitizeHtml(html) {
    const allowedTags = [
      'p', 'strong', 'em', 'blockquote', 'code', 'a', 
      'h1', 'h2', 'h3', 'h4', 'h5', 'h6',
      'ul', 'ol', 'li', 'dl', 'dt', 'dd'
    ];
    
    // Use a simpler approach that creates a new DOM tree
    const parser = new DOMParser();
    const doc = parser.parseFromString(html, 'text/html');
    const result = document.createElement('div');
    
    // Function to process a node and its children
    function cleanNode(node) {
      // For text nodes, just create a copy
      if (node.nodeType === Node.TEXT_NODE) {
        return document.createTextNode(node.textContent);
      }
      
      // Skip non-element nodes
      if (node.nodeType !== Node.ELEMENT_NODE) {
        return null;
      }
      
      const tagName = node.tagName.toLowerCase();
      
      // If it's not an allowed tag, just process its children
      if (!allowedTags.includes(tagName)) {
        const fragment = document.createDocumentFragment();
        
        for (const child of node.childNodes) {
          const cleanedChild = cleanNode(child);
          if (cleanedChild) {
            fragment.appendChild(cleanedChild);
          }
        }
        
        return fragment;
      }
      
      // Create a new clean element
      const cleanElement = document.createElement(tagName);
      
      // Only copy the href attribute for links
      if (tagName === 'a' && node.hasAttribute('href')) {
        cleanElement.setAttribute('href', node.getAttribute('href'));
      }
      
      // Process all child nodes
      for (const child of node.childNodes) {
        const cleanedChild = cleanNode(child);
        if (cleanedChild) {
          cleanElement.appendChild(cleanedChild);
        }
      }
      
      return cleanElement;
    }
    
    // Process the body content
    const bodyContent = doc.body;
    for (const childNode of bodyContent.childNodes) {
      const cleanedNode = cleanNode(childNode);
      if (cleanedNode) {
        result.appendChild(cleanedNode);
      }
    }
    
    return result.innerHTML;
  }
  
  // Function to pretty format HTML with indentation
  function formatHtml(html) {
    let formatted = '';
    let indent = 0;
    
    // Function to get indentation string
    function getIndent(level) {
      // Ensure level is non-negative to avoid RangeError
      const safeLevel = Math.max(0, level);
      return '  '.repeat(safeLevel);
    }
    
    // Split HTML by tags
    const parts = html.split(/(<\/?[^>]+>)/);
    
    for (let i = 0; i < parts.length; i++) {
      const part = parts[i].trim();
      if (!part) continue;
      
      // Check if it's a tag
      if (part.startsWith('<')) {
        // Closing tag
        if (part.startsWith('</')) {
          indent = Math.max(0, indent - 1); // Prevent negative indent
          formatted += getIndent(indent) + part + '\n';
        }
        // Self-closing tag
        else if (part.endsWith('/>')) {
          formatted += getIndent(indent) + part + '\n';
        }
        // Opening tag
        else {
          formatted += getIndent(indent) + part + '\n';
          // Don't increase indent for inline elements
          if (!part.match(/<(strong|em|code|a)[^>]*>/i)) {
            indent++;
          }
        }
      }
      // Content
      else if (part) {
        formatted += getIndent(indent) + part + '\n';
      }
    }
    
    return formatted;
  }
  
  // Get DOM elements
  const pasteArea = document.getElementById('paste-area');
  const outputContainer = document.getElementById('output-container');
  const htmlOutput = document.getElementById('html-output');
  const previewContent = document.getElementById('preview-content');
  const copyButton = document.getElementById('copy-button');
  const clearButton = document.getElementById('clear-button');
  
  // Handle paste event
  pasteArea.addEventListener('paste', function(e) {
    // Let the paste happen normally first
    setTimeout(function() {
      // Get pasted content
      const pastedContent = pasteArea.innerHTML;
      
      if (pastedContent) {
        // Sanitize the HTML to only keep allowed tags
        const sanitizedHtml = sanitizeHtml(pastedContent);
        
        // Format the HTML nicely
        const formattedHtml = formatHtml(sanitizedHtml);
        
        // Display the HTML code with escaped characters
        htmlOutput.value = formattedHtml;
        
        // Show the output container
        outputContainer.style.display = 'block';
        
        try {
          // Get the iframe element
          const previewFrame = document.getElementById('preview-frame');
          
          // Create a blob with the HTML content
          const blob = new Blob([`
            <!DOCTYPE html>
            <html>
            <head>
              <meta charset="UTF-8">
              <meta name="viewport" content="width=device-width, initial-scale=1.0">
              <style>
                body {
                  font-family: Helvetica, Arial, sans-serif;
                  line-height: 1.5;
                  padding: 15px;
                  margin: 0;
                }
              </style>
            </head>
            <body>
              ${sanitizedHtml}
            </body>
            </html>
          `], {type: 'text/html'});
          
          // Create a URL for the blob
          const blobURL = URL.createObjectURL(blob);
          
          // Set the iframe source to the blob URL
          previewFrame.src = blobURL;
          
          // Clean up the blob URL when the iframe loads
          previewFrame.onload = function() {
            URL.revokeObjectURL(blobURL);
          };
        } catch (error) {
          console.error('Error updating preview:', error);
        }
        
        // Show success message
        pasteArea.innerHTML = '<p class="success-message">Content pasted. HTML extracted and cleaned.</p>';
      }
    }, 10);
  });
  
  // Reset paste area when clicked
  pasteArea.addEventListener('focus', function() {
    if (pasteArea.textContent.includes('Content pasted')) {
      pasteArea.innerHTML = '';
    }
  });
  
  // Copy HTML to clipboard
  copyButton.addEventListener('click', function() {
    htmlOutput.select();
    document.execCommand('copy');
    
    const originalText = copyButton.textContent;
    copyButton.textContent = 'Copied!';
    
    setTimeout(function() {
      copyButton.textContent = originalText;
    }, 1500);
  });
  
  // Clear all content
  clearButton.addEventListener('click', function() {
    pasteArea.innerHTML = '';
    htmlOutput.value = '';
    document.getElementById('preview-frame').src = 'about:blank';
    outputContainer.style.display = 'none';
  });
  </script>
</body>
</html>
